# -*- mode: snippet -*-
# name: shiny module example2
# key: shiny.module.example2
# key: shiny_module_example2
# contributor: Shuguang Sun
# --
## shiny > 1.50
mod_dataviz_ui <- function(
  id,
  type = c("point", "hist", "boxplot", "bar")
) {
  # Setting an header with the specified type of graph
  h4(
    sprintf( "Create a geom_%s", type )
  ),
  # [ ... ]
  # We want to allow a coord_flip only with barplots
  if (type == "bar"){
    checkboxInput(
      ns("coord_flip"),
      "coord_flip"
    )
  },
  # [ ... ]
  # We want to display the bins input only
  # when the type is histogram
  if (type == "hist") {
    numericInput(
      ns("bins"),
      "bins",
      30,
      1,
      150,
      1
    )
  },
  # [ ... ]
  # The title input will be added to the graph
  # for every type of graph
  textInput(
    ns("title"),
    "Title",
    value = ""
  )
}

## And in the module server:

mod_dataviz_server <- function(
  input,
  output,
  session,
  type
) {
  # [ ... ]
  if (type == "point") {
    # Defining the server logic when the type is point
    # When the type is point, we have access to input$x,
    # input$y, input$color, and input$palette,
    # so we reuse them here
    ggplot(
      big_epa_cars,
      aes(
        .data[[input$x]],
        .data[[input$y]],
        color = .data[[input$color]])
    )  +
      geom_point()+
      scale_color_manual(
        values = color_values(
          1:length(
            unique(
              pull(
                big_epa_cars,
                .data[[input$color]])
            )
          ),
          palette = input$palette
        )
      )
  }
  # [ ... ]
  if (type == "hist") {
    # Defining the server logic when the type is hist
    # When the type is point, we have access to input$x,
    # input$color, input$bins, and input$palette
    # so we reuse them here
    ggplot(
      big_epa_cars,
      aes(
        .data[[input$x]],
        fill = .data[[input$color]]
      )
    ) +
      geom_histogram(bins = input$bins)+
      scale_fill_manual(
        values = color_values(
          1:length(
            unique(
              pull(
                big_epa_cars,
                .data[[input$color]]
              )
            )
          ),
          palette = input$palette
        )
      )
  }
}


## Then, the UI of the entire application is:

app_ui <- function() {
  # [...]
  tagList(
    fluidRow(
      # Setting the first tab to be of type point
      id = "geom_point",
      mod_dataviz_ui(
        "dataviz_ui_1",
        type = "point"
      )
    ),
    fluidRow(
      # Setting the second tab to be of type point
      id = "geom_hist",
      mod_dataviz_ui(
        "dataviz_ui_2",
        type = "hist"
      )
    )
  )
}

## And the app_server() of the application:


app_server <- function(input, output, session) {
  # This app has been built before shiny 1.5.0,
  # so we use the callModule structure
  #
  # We here call the server module on their
  # corresponding id in the UI, and set the
  # parameter of the server function to
  # match the correct type of input
  callModule(mod_dataviz_server, "dataviz_ui_1", type = "point")
  callModule(mod_dataviz_server, "dataviz_ui_2", type = "hist")
}

shinyApp(app_ui, app_server)